package com.aidex.biz.utils;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * 签名方法
 */

@Slf4j
@Component
public class SignUtilsThird {
    public static boolean checkSign(String body, String apiKey, String timestamp, String apiSecret, String sign) {
        String generateSign = generateSign(body, apiKey, timestamp, apiSecret);
        log.info("generateSign: {}, passinSign: {}", generateSign, sign);

        return generateSign.equals(sign);
    }

    public static String generateSign(String body, String apiKey, String timestamp, String apiSecret) {
        // 第一步：参数排序
        // 准备待 hash 数据
        Map<String, String> params = new HashMap<>();
        params.put("apiKey", apiKey);
        params.put("timestamp", timestamp);
        params.put("apiSecret", apiSecret);
        params.put("body", body);

        List<String> keys = Lists.newArrayList();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            keys.add(entry.getKey());
        }
        Collections.sort(keys);

        // 第二步：把所有参数名和参数值串在一起
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotEmpty(apiSecret)) {
            sb.append(apiSecret);
        }
        for (String key : keys) {
            sb.append(key).append(params.get(key).trim());
        }
        if (StringUtils.isNotEmpty(apiSecret)) {
            sb.append(apiSecret);
        }
        String encryptionKey = sb.toString().trim();

        // 第三步：加签
        try {
            return genMd5(encryptionKey);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private static String genMd5(String info) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte[] infoBytes = info.getBytes();
        md5.update(infoBytes);
        byte[] sign = md5.digest();
        return byteArrayToHex(sign);
    }

    private static String byteArrayToHex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toLowerCase());
        }
        return sign.toString();
    }
}
